package models

import (
	"data_view/core"
	"data_view/utils"
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"strings"
)

var ChartDataHandlers = make(map[string]ChartData)

type ChartDataHandler struct {
	RunGetDataFromDB  func(db *sql.DB, chartDataParams *core.ChartDataParams) (string, error)
	RunGetDataFromCsv func(chartDataParams *core.ChartDataParams) (string, error)
}

func (handler *ChartDataHandler) GetDataFromDB(db *sql.DB, chartDataParams *core.ChartDataParams) (string, error) {
	return handler.RunGetDataFromDB(db, chartDataParams)
}

func (handler *ChartDataHandler) GetDataFromCsv(chartDataParams *core.ChartDataParams) (string, error) {
	return handler.RunGetDataFromCsv(chartDataParams)
}

type ChartData interface {
	GetDataFromDB(db *sql.DB, chartDataParams *core.ChartDataParams) (string, error)
	GetDataFromCsv(chartDataParams *core.ChartDataParams) (string, error)
}

func GetChartData(chartDataParams *core.ChartDataParams) (string, error) {
	var (
		err        error
		dataSource *DataSource
		db         *sql.DB
		dataResult string
	)
	// 此处判断图表类型
	chartType := chartDataParams.ChartType
	// 此处判断图表数据源类型
	dataSourceType := chartDataParams.DataSourceType
	if strings.EqualFold(dataSourceType, core.DataBase) {
		// 如果是DB类型的数据源，需要获取好各种数据库连接对象
		databaseString := chartDataParams.Database
		var databaseId uint64
		if err := utils.StrToUint(databaseString, &databaseId); err != nil {
			return core.EmptyString, err
		}
		if dataSource, err = GetDataSourceById(databaseId); err != nil {
			return core.EmptyString, err
		}
		// 构建数据库访问对象
		dataSourceType := dataSource.DataSourceType
		if strings.EqualFold(dataSourceType, core.MySQL) {
			urlTemplate := "%s:%s@tcp(%s:%d)/%s?charset=utf8&multiStatements=true"
			url := fmt.Sprintf(urlTemplate,
				dataSource.DataSourceUsername,
				dataSource.DataSourcePassword,
				dataSource.DataSourceIp,
				dataSource.DataSourcePort,
				dataSource.DataSourceDatabaseName)
			if db, err = sql.Open("mysql", url); err != nil {
				return core.EmptyString, err
			}
			defer db.Close()
		} else if strings.EqualFold(dataSourceType, core.Oracle) {
		} else if strings.EqualFold(dataSourceType, core.SQLServer) {
		} else if strings.EqualFold(dataSourceType, core.DB2) {
		} else {
			return core.EmptyString, errors.New(core.DataSourceTypeError)
		}
		if dataResult, err = ChartDataHandlers[chartType].GetDataFromDB(db, chartDataParams); err != nil {
			return dataResult, err
		}
		return dataResult, nil
	} else if strings.EqualFold(dataSourceType, core.CSV) {
		if dataResult, err = ChartDataHandlers[chartType].GetDataFromCsv(chartDataParams); err != nil {
			return dataResult, err
		}
		return dataResult, nil
	} else {
		return core.EmptyString, errors.New(core.DataSourceTypeError)
	}
}
